package com.fingard.xml;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import com.fingard.text.StringHelper;
import com.fingard.text.XmlHelper;

public class XElement {
    public String innerText = "";
    public String name = "";

    /**标签是否已正常关闭*/
    public boolean isClosed = false;
    
    /**是否为自闭合，自闭合示例： <a />*/
    public boolean isSelfClosed = false;

    private HashMap<String, ArrayList<XElement>> hashMapChildXE;

    public XElement parentXElement;

    public XElement() {
    }

    public HashMap<String, String> hashMapAttributes = null;

    public String getAttrValue(String p_attr) {
        if (hashMapAttributes != null && hashMapAttributes.containsKey(p_attr)) {
            return hashMapAttributes.get(p_attr);
        } else {
            return "";
        }
    }

    public boolean getAttrValueAsBool(String p_attr) {
        String aValue = getAttrValue(p_attr);
        if (StringHelper.hasAnyChar(aValue)) {
            if (aValue.trim().toLowerCase().equals("true")) {
                return true;
            }
        }
        return false;
    }

    private ArrayList<String> attrOrder = null;//记录顺序

    /**
     * 增加属性
     */
    public void addAttr(String p_key, String p_value) {
        if (attrOrder == null) {
            attrOrder = new ArrayList<String>();
        }
        if (hashMapAttributes == null) {
            hashMapAttributes = new HashMap<String, String>();
        }
        attrOrder.add(p_key);
        hashMapAttributes.put(p_key, p_value);
    }

    public String getNameAttrForWrite() {
        if (attrOrder != null && attrOrder.size() > 0 && hashMapAttributes != null && hashMapAttributes.size() > 0) {
            StringBuilder sb = new StringBuilder();
            sb.append("<" + name);
            for (String eachKey : attrOrder) {
                String eachValue = "";
                if (hashMapAttributes.containsKey(eachKey)) {
                    eachValue = hashMapAttributes.get(eachKey);
                }
                sb.append(" " + eachKey + "=\"" + XmlHelper.encode(eachValue) + "\"");
            }
            sb.append(">");
            return sb.toString();
        }
        return "";
    }
    
    public String getOnlyAttrForWrite() {
        if (attrOrder != null && attrOrder.size() > 0 && hashMapAttributes != null && hashMapAttributes.size() > 0) {
            StringBuilder sb = new StringBuilder();
            for (String eachKey : attrOrder) {
                String eachValue = "";
                if (hashMapAttributes.containsKey(eachKey)) {
                    eachValue = hashMapAttributes.get(eachKey);
                }
                sb.append(" " + eachKey + "=\"" + XmlHelper.encode(eachValue) + "\"");
            }
            return sb.toString();
        }
        return "";
    }

    public XElement(String p_name, String p_innerText) {
        name = p_name;
        innerText = p_innerText;
        isClosed = true;
    }

    public XElement(String p_name, String p_innerText, boolean hasCDATA) {
        name = p_name;
        if (hasCDATA == true) {
            innerText = "<![CDATA[" + p_innerText + "]]>";
        } else {
            innerText = p_innerText;
        }
        isClosed = true;
    }

    private int subNodeCount = 0;//子节点个数

    public int sizeSubNode() {
        return subNodeCount;
    }

    private ArrayList<String> listOrder;//记录子节点顺序

    public void addChild(XElement child) {
        subNodeCount++;
        if (hashMapChildXE == null) {
            hashMapChildXE = new HashMap<String, ArrayList<XElement>>();
            listOrder = new ArrayList<String>();
        }
        child.parentXElement = this;
        if (!hashMapChildXE.containsKey(child.name)) {
            hashMapChildXE.put(child.name, new ArrayList<XElement>());
            listOrder.add(child.name);
        }
        hashMapChildXE.get(child.name).add(child);
    }

    public String getSingleTextNotNull(String p_NameOrPath) throws Exception {
        String str = getSingleText(p_NameOrPath);
        if (str == null || str.equals("null")) {
            return "";
        } else {
            return str;
        }
    }

    public String getSingleTextNotNullUpperCase(String p_NameOrPath) throws Exception {
        p_NameOrPath = StringHelper.toUpperCaseFirstOne(p_NameOrPath);
        String str = getSingleText(p_NameOrPath);
        if (str == null) {
            return "";
        } else {
            return str;
        }
    }

    public String getSingleText(String p_NameOrPath) throws Exception {
        String[] tmpNames = p_NameOrPath.split("/");
        XElement tmpXElement = null;
        for (int i = 0; i < tmpNames.length; i++) {
            if (i == 0) {
                tmpXElement = getSingleChild(tmpNames[i]);
            } else {
                tmpXElement = tmpXElement.getSingleChild(tmpNames[i]);
            }
            if (tmpXElement == null) {
                return "";
            }
            if (!tmpXElement.isClosed) {
                throw new Exception("节点：" + tmpNames[i] + "未正常关闭");
            }
        }
        if (tmpXElement == null) {
            return "";
        } else {
            return tmpXElement.innerText;
        }
    }

    //处理重复节点的情况如<status><rep></rep></status><status>0</status>
    public String getSingleTextByIndex(String p_NameOrPath, int index) throws Exception {
        String[] tmpNames = p_NameOrPath.split("/");
        XElement tmpXElement = null;
        for (int i = 0; i < tmpNames.length; i++) {
            if (i == 0) {
                tmpXElement = getSingleChildByIndex(tmpNames[i], index);
            } else {
                tmpXElement = tmpXElement.getSingleChildByIndex(tmpNames[i], index);
            }
            if (tmpXElement == null) {
                return null;
            }
            if (!tmpXElement.isClosed) {
                throw new Exception("节点：" + tmpNames[i] + "未正常关闭");
            }
        }
        if (tmpXElement == null) {
            return null;
        } else {
            return tmpXElement.innerText;
        }
    }

    public void setSingleText(String p_childName, String p_value) throws Exception {
        if (hashMapChildXE.containsKey(p_childName)) {
            if (hashMapChildXE.get(p_childName).get(0).isClosed) {
                hashMapChildXE.get(p_childName).get(0).innerText = p_value;
            } else {
                throw new Exception("节点：" + p_childName + "未正常关闭");
            }
        }
    }

    public XElement getSingleChild(String p_childName) {
        if (hashMapChildXE != null && hashMapChildXE.containsKey(p_childName)) {
            return hashMapChildXE.get(p_childName).get(0);
        }
        return null;
    }

    public XElement getSingleChildByIndex(String p_childName, int index) {
        if (hashMapChildXE != null && hashMapChildXE.containsKey(p_childName)) {
            return hashMapChildXE.get(p_childName).get(index);
        }
        return null;
    }

    public ArrayList<XElement> getChildList(String p_childName) {
        if (hashMapChildXE != null && hashMapChildXE.containsKey(p_childName)) {
            return hashMapChildXE.get(p_childName);
        }
        return null;
    }

    public ArrayList<XElement> getAllChildList() {
        ArrayList<XElement> retList = null;
        if (listOrder != null && listOrder.size() > 0) {
            retList = new ArrayList<XElement>();
            Iterator<String> iter = listOrder.iterator();// hashMapChildXE.keySet().iterator();
            while (iter.hasNext()) {
                String eachKey = iter.next();
                ArrayList<XElement> listEach = hashMapChildXE.get(eachKey);
                if (listEach != null && listEach.size() > 0) {
                    retList.addAll(listEach);
                }
            }
        }
        return retList;
    }

    public int countChildren() {
        int retInt = 0;
        if (listOrder != null && listOrder.size() > 0) {
            Iterator<String> iter = listOrder.iterator();// hashMapChildXE.keySet().iterator();
            while (iter.hasNext()) {
                String eachKey = iter.next();
                ArrayList<XElement> listEach = hashMapChildXE.get(eachKey);
                if (listEach != null && listEach.size() > 0) {
                    retInt = retInt + listEach.size();
                }
            }
        }
        return retInt;
    }


    public boolean isAllClosed(StringBuilder p_sbLog) {
        if (isClosed == false) {
            p_sbLog.append("标签：" + name + "未闭合");
            return false;
        }
        if (hashMapChildXE != null && hashMapChildXE.size() > 0) {
            Iterator<String> iter = hashMapChildXE.keySet().iterator();
            while (iter.hasNext()) {
                String eachKey = iter.next();
                ArrayList<XElement> listEach = hashMapChildXE.get(eachKey);
                for (int i = 0; i < listEach.size(); i++) {
                    if (listEach.get(i).isAllClosed(p_sbLog) == false) {
                        //p_sbLog.append("标签："+listEach.get(i).name+"未闭合");
                        return false;
                    }
                }
            }
        }
        return true;
    }
}
